package com.zhengwl.study.main;

import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;

import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
import com.zhengwl.study.algorithm.Sudoku;
import com.zhengwl.study.aop.IBusiness;
import com.zhengwl.study.aop.IRest;
import com.zhengwl.study.aop.LogIntercept;
import com.zhengwl.study.aop.LogInvocationHandler;
import com.zhengwl.study.aop.MyTranslator;
import com.zhengwl.study.aop.Worker;
import com.zhengwl.study.constant.Color;
import com.zhengwl.study.datastruct.BagQuestion;
import com.zhengwl.study.datastruct.BinarySortTree;
import com.zhengwl.study.model.Person;
import com.zhengwl.study.model.Student;
import com.zhengwl.study.model.TestA;
import com.zhengwl.study.nest.Outer;
import com.zhengwl.study.nio.FileManager;
import com.zhengwl.study.sort.BinarySearch;
import com.zhengwl.study.sort.InsertSort;
import com.zhengwl.study.sort.Sort;
import com.zhengwl.study.sort.Sort.SortType;
import com.zhengwl.study.sort.SwapSort;
import com.zhengwl.study.thread.DefaultThreadPool;
import com.zhengwl.study.thread.ThreadCallable;

import javassist.ClassPool;
import javassist.Loader;
import net.sf.cglib.proxy.Enhancer;

/**
 * Hello world!
 *
 */
public class App {
	// private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;//=8192=1024*8
	private static final int MAXPAGESIZE=10_0000;
	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		
	int[][] array={{0,0,0,2,0,0,9,3,0},{0,0,6,5,3,9,1,8,4},{0,3,0,8,0,1,6,7,2},
			{2,8,0,6,7,5,0,9,0},{0,0,0,0,0,0,2,1,7},{9,0,0,4,1,0,5,6,8},
			{0,0,5,0,0,0,0,0,6},{4,0,0,0,2,3,0,5,9},{0,0,0,7,0,0,3,4,1}};

	Sudoku temp=new Sudoku(array);
	temp.getResult(0, 0);
	 for(int i=0;i<9;i++){
     	boolean b=false;
     	for(int j=0;j<9;j++){
     		 
         }
     	System.out.println(Arrays.toString(array[i]));
     }
	
	//	testSort();
		
//		Runnable myRunnable = new Runnable() {
//			public void run() {
//				testStream();
//				System.out.println("Runnable running");
//			}
//		};
//		Thread thread = new Thread(myRunnable);	
//		td.start();
//		thread.start();
//		td.run();
		//testStream();
		
//		try {
//			testCustomerClassLoader(args);
//		} catch (Throwable e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
//		Son son=new Son();
//		GrandFather gFather=son;
//		System.out.println("name:"+gFather.name+",name:"+gFather.getName());
//		System.out.println("name:"+gFather.name+",age:"+gFather.getAge());
	}

	public static void testEnum() {
		System.out.println(Color.GREEN);// GREEN
	}

	public static void testSort() {
		System.out.println("-----------testSort start-----------");
		int[] items = { 13, 1, 3, 4, 55, 66, 77, 99, 21, 89, 55 };
		//int[] items = {12, 1, 3, 4};
		Sort sort = new SwapSort(SortType.QuickSort);
		sort.sort(items);
		System.out.println("-----------testSort end-----------");
	}
	
	public static void testBinarySearch() {
		System.out.println("-----------testBinarySearch start-----------");
		int[] items = { 0, 1, 3, 4, 55, 66, 77, 99 };
		int val=55;
		BinarySearch search=new BinarySearch(items);
		int index=search.search(val);
		System.out.println("查找值得索引为："+index);
		System.out.println("-----------testBinarySearch end-----------");
	}

	public static void testJoiner() {
		System.out.println("-----------testJoiner start-----------");
		List<Integer> testi = Arrays.asList(12, 890, 16895);
		System.out.println(Joiner.on(",").join(testi));
		System.out.println("-----------testJoiner end-----------");
	}

	public static void testStaticClass() {
		System.out.println("-----------testStaticClass start-----------");
		Outer.StaticNested staticinner = new Outer.StaticNested();
		staticinner.setHeight(20);
		Outer.Nested inner=new Outer().new Nested();
		inner.setHeight(333);
		System.out.println("staticinner height:" + staticinner.getHeight() + ",inner height:" + inner.getHeight());
		System.out.println("-----------testStaticClass end-----------");
	}

	public static void testOptional() {
		TestA a = new TestA(1, "zhengwl");
		Optional<String> xx = Optional.fromNullable(a.getTestB().getName());
		System.out.println(xx);

		Function<String, Integer> lengthFunction = new Function<String, Integer>() {
			public Integer apply(String string) {
				return string.length();
			}
		};
		Predicate<String> allCaps = new Predicate<String>() {
			public boolean apply(String string) {
				return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
			}
		};
		List<String> strings = Lists.newArrayList("ggg", "WDDD", "gdDDgx", "LiSi", "zhaoWu");
		Multiset<Integer> lengths = HashMultiset.create(Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction));
	}

	public static void testPredicate() {
		Set<TestA> items = Sets.newHashSet(new TestA(3, "zhangsan"), new TestA(27, "lisi"), new TestA(27, "lisi"));
		final int age = 22;
		Predicate<TestA> allage = new Predicate<TestA>() {
			@Override
			public boolean apply(TestA string) {
				return string.getAge() > age;
			}
		};
		List<TestA> lengths = Lists.newArrayList(Iterables.filter(items, allage));
		for (TestA testA : items) {
			System.out.println(testA.getName() + testA.getAge() + testA.hashCode());
		}
	}

	public static void testPartition() {
		int cap = 10;
		List<Integer> intCollection = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 12, 34, 33, 45, 46, 77, 78, 98);
		List<List<Integer>> subSets = Lists.partition(intCollection, cap);
		System.out.println("-----------testixx-----------" + subSets.size());
	}

	public static void testHashCode() {
		TestA zhangsan = new TestA(3, "zhangsan");
		TestA lisi = new TestA(23, "lisi");
		TestA lisi2 = new TestA(27, "lisi");
		System.out.println(zhangsan.hashCode());
		System.out.println("----------------------");
		System.out.println(lisi.toString() + "\n" + lisi2.toString());
		System.out.println(lisi.toString().hashCode() == lisi2.toString().hashCode());
		System.out.println("*****************");
		System.out.println("赵钱孙李".hashCode());
	}
	
	public static void testAop() {
		//需要代理的接口，被代理类实现的多个接口都必须在这里定义
		Class[] proxyInterface = new Class[] { IBusiness.class, IRest.class }; 
		//构建AOP的Advice，这里需要传入业务类的实例 
		LogInvocationHandler handler = new LogInvocationHandler(new Worker()); 
		//生成代理类的字节码加载器 
		ClassLoader classLoader = App.class.getClassLoader(); 
		//织入器，织入代码并生成代理类 
		IBusiness proxyBusiness = (IBusiness) Proxy.newProxyInstance(classLoader, proxyInterface, handler); 
		//使用代理类的实例来调用方法。
		proxyBusiness.doWork(); 
		((IRest) proxyBusiness).doSleep();
	}
	
	public static void testByteCodeGe() { 
		//创建一个织入器
		Enhancer enhancer = new Enhancer(); 
		//设置父类
		enhancer.setSuperclass(Worker.class); 
		//设置需要织入的逻辑 
		enhancer.setCallback(new LogIntercept()); 
		//使用织入器创建子类 
		IBusiness newBusiness = (IBusiness) enhancer.create(); 
		newBusiness.doWork();
	}
	
	public static void testCustomerClassLoader(String[] args) throws Throwable { 
		//获取存放CtClass的容器ClassPool 
		ClassPool cp = ClassPool.getDefault(); 
		//创建一个类加载器 
		Loader cl = new Loader();
		//增加一个转换器 
		cl.addTranslator(cp, new MyTranslator());
		//启动MyTranslator的main函数
		cl.run("com.ctrip.market.destination.test.aop.MyTranslator", args);
	}
	
	public static void testThreadCallable(){ 
		ThreadCallable td=new ThreadCallable();
		//1.执行 Callable 方式，需要 FutureTask 实现类的支持，用于接收运算结果。
		FutureTask<Integer> rel=new FutureTask<>(td);
		new Thread(rel).start();	
		//2.接收线程运算后的结果
		try {
			Integer sum = rel.get();
			System.out.println(sum);
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}		
	}
	
	public static void testBST(){
		BinarySortTree bst = new BinarySortTree();
		/**构建的二叉树没有相同元素*/
		int[] num = {4,7,2,1,10,6,9,3,8,11,2, 0, -2};
		for(int i = 0; i < num.length; i++){
			bst.insertBST(num[i]);
		}
		bst.nrInOrderTraverse();
		System.out.println(bst.searchBST(10));
//		bst.deleteBST(2);
//		bst.nrInOrderTraverse();
	}
	
	public static void testBag(){
		int[] weight=new int[]{1,3,4,3,1};
		int[] values=new int[]{2,3,14,5,1};
		BagQuestion bag=new BagQuestion(weight, values);
		int rel=bag.solve(4);
		int reldp=bag.solvedp(4);
		System.out.println("贪心："+rel+",dp:"+reldp);
	}
	public static double  testGetDistance(double lat1, double lng1, double lat2, double lng2) {
		// 地球半径
		double EARTHRADIUS = 6378.137;
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTHRADIUS;
		s = Math.round(s * 10000) / 10000;
		return s;
	}
	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}
	
	public static void testStream() {
		List<Student> stus=Lists.newArrayList(new Student(5,"zhangsan","回民小学"),
				new Student(13,"lisi","大名初中"),
				new Student(2, "zhouwu",null));
		//stus.forEach(e->System.out.println(e.getName()));		
		//stus.stream().map(n->new Person(n.getAge(),n.getName())).collect(Collectors.toList()).forEach(e->System.out.println(e.getAge()));
		stus.stream().sorted(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				return -o1.getAge()+o2.getAge();
			}
		}).forEach(e->System.out.println(e.getAge()));;
	}
	
	public static void testThreadPool(){
		DefaultThreadPool tp=new DefaultThreadPool(2);
		tp.execute(new Runnable() {
			public void run() {
				testStream();
				System.out.println("Runnable running");
			}
		});
		tp.execute(new Runnable() {			
			@Override
			public void run() {
				System.out.println("ThreadPool running");
				
			}
		});
		Thread td = new Thread() {
			public void run() {
				System.out.println("Thread Running");
			}
		};
	}

}
